package com.summary.richtext.utils.word;

import org.apache.poi.xwpf.usermodel.*;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * 生成word报告的工具类
 * 
 * @author magh@sunwayworld.com 2019年12月6日
 *
 */
public class Word2007Utils {

    /**
     * 替换指定字符串
     * 
     * @param document
     * @param dataMap
     *            替换的键值对
     */
    public static void replaceAll(XWPFDocument document, Map<String, Object> dataMap) {

        // 处理段落
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        replaceInParagraphs(dataMap, paragraphs);
       /* for (XWPFParagraph paragraph : paragraphs) {
            List<XWPFRun> runs = paragraph.getRuns();
            for (XWPFRun run : runs) {
                replaceRunText(dataMap, run);
            }
        }*/

        // 处理表格
        List<XWPFTable> tables = document.getTables();
        for (XWPFTable table : tables) {
            List<XWPFTableRow> rows = table.getRows();
            for (XWPFTableRow row : rows) {
                List<XWPFTableCell> cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {

                    List<XWPFParagraph> cellParagraphs = cell.getParagraphs();
                    replaceInParagraphs(dataMap, cellParagraphs);
                   /* if (cellParagraphs != null && cellParagraphs.size() > 0) {

                        List<XWPFRun> runs = cellParagraphs.get(0).getRuns();
                        if (runs != null && runs.size() > 0) {
                            for (XWPFRun run : runs) {
                                replaceRunText(dataMap, run);
                            }
                        }
                    }*/
                }
            }
        }

        // 处理页眉
        List<XWPFHeader> headerList = document.getHeaderList();

        headerList.forEach(e -> {
            List<XWPFParagraph> headerParagraphs = e.getParagraphs();

            if (headerParagraphs != null && headerParagraphs.size() > 0) {

                List<XWPFRun> runs = headerParagraphs.get(0).getRuns();
                if (runs != null && runs.size() > 0) {

                    runs.forEach(run -> replaceRunText(dataMap, run));
                }
            }
        });
        
        List<XWPFFooter> footerList =document.getFooterList();
        footerList.forEach(e -> {
            List<XWPFParagraph> footerParagraphs = e.getParagraphs();

            if (footerParagraphs != null && footerParagraphs.size() > 0) {

                List<XWPFRun> runs = footerParagraphs.get(0).getRuns();
                if (runs != null && runs.size() > 0) {

                    runs.forEach(run -> replaceRunText(dataMap, run));
                }
            }
        });

    }

    // 替换文本数据
    private static void replaceRunText(Map<String, Object> dataMap, XWPFRun run) {
        String text = run.getText(0);
        if (text != null) {
            boolean isSetText = false;
            for (Entry<String, Object> entry : dataMap.entrySet()) {
                String key = entry.getKey();
                String value = String.valueOf(entry.getValue());
                if (text.indexOf(key) != -1) {
                    isSetText = true;
                    text = text.replaceAll(key, value);
                }
                if (isSetText) {
                    run.setText(text, 0);
                }
            }
        }
    }
    private static long replaceInParagraphs(Map<String, Object> replacements, List<XWPFParagraph> xwpfParagraphs) {
        long count = 0;
        for (XWPFParagraph paragraph : xwpfParagraphs) {
            List<XWPFRun> runs = paragraph.getRuns();

            for (Entry<String, Object> replPair : replacements.entrySet()) {
                String find = replPair.getKey();
                String repl = String.valueOf(replPair.getValue());;
                TextSegment found = paragraph.searchText(find, new PositionInParagraph());
                if ( found != null ) {
                    count++;
                    if ( found.getBeginRun() == found.getEndRun() ) {
                        // whole search string is in one Run
                        XWPFRun run = runs.get(found.getBeginRun());
                        String runText = run.getText(run.getTextPosition());
                        String replaced = runText.replace(find, repl);
                        run.setText(replaced, 0);
                    } else {
                        // The search string spans over more than one Run
                        // Put the Strings together
                        StringBuilder b = new StringBuilder();
                        for (int runPos = found.getBeginRun(); runPos <= found.getEndRun(); runPos++) {
                            XWPFRun run = runs.get(runPos);
                            b.append(run.getText(run.getTextPosition()));
                        }
                        String connectedRuns = b.toString();
                        String replaced = connectedRuns.replace(find, repl);

                        // The first Run receives the replaced String of all connected Runs
                        XWPFRun partOne = runs.get(found.getBeginRun());
                        partOne.setText(replaced, 0);
                        // Removing the text in the other Runs.
                        for (int runPos = found.getBeginRun()+1; runPos <= found.getEndRun(); runPos++) {
                            XWPFRun partNext = runs.get(runPos);
                            partNext.setText("", 0);
                        }
                    }
                }
            }
        }
        return count;
    }

}
